//
//  QSRequestHelper.m
//  DigitalEconomy_iOS
//
//  Created by Ding on 2020/3/23.
//  Copyright © 2020 DingC. All rights reserved.
//

#import "QSRequestHelper.h"
//#import "AFNetworkActivityIndicatorManager.h"
#import "NSData+QSData.h"
static NSMutableArray *_allSessionTask; //请求task数组
static AFHTTPSessionManager *_sessionManager; //
@interface QSRequestHelper ()
//AFNetworking stuff
@property (nonatomic, strong) AFHTTPSessionManager *sessionManager;

@end
@implementation QSRequestHelper

#pragma mark - **************** 请求
+ (NSURLSessionTask *)executeRequestWithType:(QSRequestType)type
                                     headers:(NSMutableDictionary *)headerDic
                                  requestUrl:(NSString *)requestUrl
                                requestCount:(int)requestCount
                                 requestBody:(NSMutableDictionary *)bodyDic
                                    andBlock:(void (^)(ResponseMessage *rspStatusAndMessage, NSDictionary *responseDataDic))block {
    return [self executeRequestWithType:type
                            contentType:QSRequestContentTypeForm
                                headers:headerDic
                             requestUrl:requestUrl
                           requestCount:requestCount
                            requestBody:bodyDic
                               andBlock:block];
}

+ (NSURLSessionTask *)executeRequestWithType:(QSRequestType)type
                                 contentType:(QSRequestContentType)contentType
                                     headers:(NSMutableDictionary *)headerDic
                                  requestUrl:(NSString *)requestUrl
                                requestCount:(int)requestCount
                                 requestBody:(NSMutableDictionary *)bodyDic
                                    andBlock:(void (^)(ResponseMessage *, NSDictionary *))block {
    DLog(@"===================== 请求的接口地址：%@   ================================",requestUrl);
    DLog(@"===================== 请求的header参数：%@   ================================",headerDic);
    DLog(@"===================== 请求的body参数：%@   ================================",bodyDic);
    
    //设置 content-Type
    if (contentType == QSRequestContentTypeJSON) {
        _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
        _sessionManager.requestSerializer.timeoutInterval = kRequestTimeoutInterval;
    } else if (contentType == QSRequestContentTypeForm) {
        _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
        _sessionManager.requestSerializer.timeoutInterval = kRequestTimeoutInterval;
    }
    
    //设置请求头
    [self setHeadParams:headerDic withAFHTTPSessionManager:_sessionManager];
    
    NSURLSessionTask *sessionTask;
    
    if (type == QSRequestTypePost) {
        //POST
        sessionTask = [_sessionManager POST:requestUrl parameters:bodyDic progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //成功后task从当前列表移除
            [[self allSessionTask] removeObject:task];
            //打印返回数据
            [self printResponseObject:responseObject error:nil];
            //回调 message  data
            block ? block([self handleResponseMessage:responseObject], [self handelResponseData:responseObject]) : nil;
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //失败后task从当前列表移除
            [[self allSessionTask] removeObject:task];
            //打印错误
            [self printResponseObject:nil error:error];
            //错误回调
            block ? block([self handleResponseMessage:nil],nil) : nil;
        }];
    } else if (type == QSRequestTypeGet) {
        //GET
        sessionTask = [_sessionManager GET:requestUrl parameters:bodyDic progress:^(NSProgress * _Nonnull downloadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            //成功后task从当前列表移除
            [[self allSessionTask] removeObject:task];
            //打印返回数据
            [self printResponseObject:responseObject error:nil];
            //回调 message  data
            block ? block([self handleResponseMessage:responseObject], [self handelResponseData:responseObject]) : nil;
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            //失败后task从当前列表移除
            [[self allSessionTask] removeObject:task];
            //打印错误
            [self printResponseObject:nil error:error];
            //错误回调
            block ? block([self handleResponseMessage:nil],nil) : nil;
        }];
    }
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil;
    return sessionTask;
}


+ (NSURLSessionTask *)executeRequestReturnArrayWithType:(QSRequestType)type
                                            contentType:(QSRequestContentType)contentType
                                                headers:(NSMutableDictionary *)headerDic
                                             requestUrl:(NSString *)requestUrl
                                           requestCount:(int)requestCount
                                            requestBody:(NSMutableDictionary *)bodyDic
                                               andBlock:(void (^)(ResponseMessage *rspStatusAndMessage, NSArray *responseDataArr))block{
                                                   DLog(@"===================== 请求的接口地址：%@   ================================",requestUrl);
                                                   DLog(@"===================== 请求的header参数：%@   ================================",headerDic);
                                                   DLog(@"===================== 请求的body参数：%@   ================================",bodyDic);
                                                   
                                                   //设置 content-Type
                                                   if (contentType == QSRequestContentTypeJSON) {
                                                       _sessionManager.requestSerializer = [AFJSONRequestSerializer serializer];
                                                       _sessionManager.requestSerializer.timeoutInterval = kRequestTimeoutInterval;
                                                   } else if (contentType == QSRequestContentTypeForm) {
                                                       _sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
                                                       _sessionManager.requestSerializer.timeoutInterval = kRequestTimeoutInterval;
                                                   }
                                                   
                                                   //设置请求头
                                                   [self setHeadParams:headerDic withAFHTTPSessionManager:_sessionManager];
                                                   
                                                   NSURLSessionTask *sessionTask;
                                                   
                                                   if (type == QSRequestTypePost) {
                                                       //POST
                                                       sessionTask = [_sessionManager POST:requestUrl parameters:bodyDic progress:^(NSProgress * _Nonnull uploadProgress) {
                                                           
                                                       } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                                                           //成功后task从当前列表移除
                                                           [[self allSessionTask] removeObject:task];
                                                           //打印返回数据
                                                           [self printResponseObject:responseObject error:nil];
                                                           //回调 message  data
                                                           block ? block([self handleResponseMessage:responseObject], [self handelResponseWithArrayData:responseObject]) : nil;
                                                       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                                                           //失败后task从当前列表移除
                                                           [[self allSessionTask] removeObject:task];
                                                           //打印错误
                                                           [self printResponseObject:nil error:error];
                                                           //错误回调
                                                           block ? block([self handleResponseMessage:nil],nil) : nil;
                                                       }];
                                                   } else if (type == QSRequestTypeGet) {
                                                       //GET
                                                       sessionTask = [_sessionManager GET:requestUrl parameters:bodyDic progress:^(NSProgress * _Nonnull downloadProgress) {
                                                           
                                                       } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                                                           //成功后task从当前列表移除
                                                           [[self allSessionTask] removeObject:task];
                                                           //打印返回数据
                                                           [self printResponseObject:responseObject error:nil];
                                                           //回调 message  data
                                                           block ? block([self handleResponseMessage:responseObject], [self handelResponseWithArrayData:responseObject]) : nil;
                                                       } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                                                           //失败后task从当前列表移除
                                                           [[self allSessionTask] removeObject:task];
                                                           //打印错误
                                                           [self printResponseObject:nil error:error];
                                                           //错误回调
                                                           block ? block([self handleResponseMessage:nil],nil) : nil;
                                                       }];
                                                   }
                                                   // 添加sessionTask到数组
                                                   sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil;
                                                   return sessionTask;
                                               }


#pragma mark - **************** 上传单张图片
+ (NSURLSessionTask *)uploadImageWithPath:(NSString *)path
                                  headers:(NSMutableDictionary *)headerDic
                                    image:(QSUploadImage *)image
                                   params:(NSDictionary *)bodyDic
                                 andBlock:(void (^)(ResponseMessage *rspStatusAndMessage, NSDictionary *responseDataDic))block {
    
    NSArray *array = [NSArray arrayWithObject:image];
    
    return [self uploadImageWithPath:path headers:headerDic photos:array params:bodyDic andBlock:block];
}

#pragma mark - **************** 上传图片
+ (NSURLSessionTask *)uploadImageWithPath:(NSString *)path
                                  headers:(NSMutableDictionary *)headerDic
                                   photos:(NSArray<QSUploadImage *> *)photos
                                   params:(NSDictionary *)bodyDic
                                 andBlock:(void (^)(ResponseMessage *rspStatusAndMessage, NSDictionary *responseDataDic))block {
    DLog(@"===================== 请求的接口地址：%@   ================================",path);
    DLog(@"===================== 请求的header参数：%@================================",headerDic);
    DLog(@"===================== 请求的photos个数：%ld================================",(long)photos.count);
    DLog(@"===================== 请求的body参数：%@   ================================",bodyDic);

    path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    //设置请求头
    [self setHeadParams:headerDic withAFHTTPSessionManager:_sessionManager];
    
    NSURLSessionTask *sessionTask = [_sessionManager POST:path parameters:bodyDic constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (int i = 0; i < photos.count; i ++) {
            QSUploadImage *uploadImage = photos[i];
            NSData *imageData = [NSData compressImageDataWithImage:uploadImage.image];
            [formData appendPartWithFileData:imageData name:uploadImage.imageName fileName:uploadImage.fileName mimeType:@"image/jpeg"];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        DLog(@"uploadProgress is %lld,总字节 is %lld",uploadProgress.completedUnitCount,uploadProgress.totalUnitCount);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        //成功后task从当前列表移除
        [[self allSessionTask] removeObject:task];
        //打印返回数据
        [self printResponseObject:responseObject error:nil];
        //回调 message  data
        block ? block([self handleResponseMessage:responseObject], [self handelResponseData:responseObject]) : nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //失败后task从当前列表移除
        [[self allSessionTask] removeObject:task];
        //打印错误
        [self printResponseObject:nil error:error];
        //错误回调
        block ? block([self handleResponseMessage:nil],nil) : nil;
    }];
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil;
    
    return sessionTask;
}

+ (NSURLSessionTask *)uploadVideoWithPath:(NSString *)path headers:(NSMutableDictionary *)headerDic videos:(NSArray<QSUploadVideo *> *)videos params:(NSDictionary *)bodyDic andBlock:(void (^)(ResponseMessage *, NSDictionary *))block {
    DLog(@"===================== 请求的接口地址：%@   ================================",path);
    DLog(@"===================== 请求的header参数：%@================================",headerDic);
    DLog(@"===================== 请求的videos个数：%ld================================",(long)videos.count);
    DLog(@"===================== 请求的body参数：%@   ================================",bodyDic);
    
    path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    //设置请求头
    [self setHeadParams:headerDic withAFHTTPSessionManager:_sessionManager];
    
    NSURLSessionTask *sessionTask = [_sessionManager POST:path parameters:bodyDic constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (int i = 0; i < videos.count; i ++) {
            QSUploadVideo *uploadVideo = videos[i];
            NSData *videoData = [NSData dataWithContentsOfURL:uploadVideo.videoURL];
            [formData appendPartWithFileData:videoData name:uploadVideo.videoName fileName:uploadVideo.fileName mimeType:@"application/octet-stream"];
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        DLog(@"uploadProgress is %lld,总字节 is %lld",uploadProgress.completedUnitCount,uploadProgress.totalUnitCount);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        //成功后task从当前列表移除
        [[self allSessionTask] removeObject:task];
        //打印返回数据
        [self printResponseObject:responseObject error:nil];
        //回调 message  data
        block ? block([self handleResponseMessage:responseObject], [self handelResponseData:responseObject]) : nil;
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        //失败后task从当前列表移除
        [[self allSessionTask] removeObject:task];
        //打印错误
        [self printResponseObject:nil error:error];
        //错误回调
        block ? block([self handleResponseMessage:nil],nil) : nil;
    }];
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil;
    
    return sessionTask;
}

#pragma mark - **************** 设置请求头
//设置请求头
+ (void)setHeadParams:(NSDictionary *)params withAFHTTPSessionManager:(AFHTTPSessionManager *)manager {
    //设置header
    if (manager
        && params
        && [params count]) {
        for(NSString *key in [params allKeys])
        {
            NSString *value = [params objectForKey:key];
            [manager.requestSerializer setValue:value forHTTPHeaderField:key];
        }
    }
}

#pragma mark - **************** 返回数据处理
/** 错误校验 */
+ (ResponseMessage *)handleResponseMessage:(id)responseObject {
    ResponseMessage *responseMessage = [[ResponseMessage alloc] init];
    if (responseObject) {
        NSDictionary *jsonObjectDic = (NSDictionary *)responseObject;
        NSString *message = [jsonObjectDic objectForKey:@"message"];
        responseMessage.message = message;
        NSString *code = [jsonObjectDic objectForKey:@"code"];
        if (code && ![code isKindOfClass:[NSNull class]]) {
            responseMessage.code = code.intValue;
            if (responseMessage.code == kResponseSuccessCode) {

            } else if (responseMessage.code == kResponseNeedLoginCode) {
                //退出登录
                [MBProgressHUD showText:message];
                [[NSUserDefaults standardUserDefaults] setBool:NO forKey:kLoginStateKey];
                [[QSUserManager sharedQSUserManager] removeUser];
                [[QSUserManager sharedQSUserManager] turnToLoginViewController];
                
            } else {
//                [QSAppKeyWindow showAutoHideHudWithText:message];
                [MBProgressHUD showText:message];
            }
        }
    } else {
        responseMessage.message = @"服务器开小差了";
        responseMessage.code = 0;
//        [QSAppKeyWindow showAutoHideHudWithText:responseMessage.message];
        [MBProgressHUD showText:responseMessage.message];
    }
    return responseMessage;
}

/** 数据处理 */
+ (NSDictionary *)handelResponseData:(id)responseObject {
    NSDictionary *jsonObjectDic = (NSDictionary *)responseObject;
    
    NSDictionary *dataJsonObjectDic = nil;
    
    NSString *code = [jsonObjectDic objectForKey:@"code"];
    if (code.longLongValue == kResponseSuccessCode) {
        dataJsonObjectDic = [jsonObjectDic objectForKey:@"data"];
    }
    return dataJsonObjectDic;
}

/** 返回数组 数据处理 */
+ (NSArray *)handelResponseWithArrayData:(id)responseObject {
    NSDictionary *jsonObjectDic = (NSDictionary *)responseObject;

    NSArray *dataJsonObjectArr = nil;
    
    NSString *code = [jsonObjectDic objectForKey:@"code"];
    if (code.longLongValue == kResponseSuccessCode) {
        dataJsonObjectArr = [jsonObjectDic objectForKey:@"data"];
    }
    return dataJsonObjectArr;
}

/** 打印返回内容 */
+ (void)printResponseObject:(id)responseObject error:(NSError *)error {
    if (error) {
        DLog(@"************************** 请求失败   **************************");
        DLog(@"%@",error.description);
        return;
    }
    DLog(@"************************** 请求获取到数据   **************************");
    NSDictionary *jsonObjectDic = (NSDictionary *)responseObject;
    NSString *desc = [jsonObjectDic description];
    if (desc) {
        desc = [NSString stringWithCString:[desc cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding];
    }
    DLog(@"%@",desc);
}

#pragma mark - **************** 取消请求
/** 取消所有请求 */
+ (void)cancelAllRequest {
    // 锁操作
    @synchronized(self) {
        [[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            [task cancel];
        }];
        [[self allSessionTask] removeAllObjects];
    }
}

/** 取消某一个URL的请求 */
+ (void)cancelRequestWithURL:(NSString *)URL {
    if (!URL) { return; }
    @synchronized (self) {
        [[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task.currentRequest.URL.absoluteString hasPrefix:URL]) {
                [task cancel];
                [[self allSessionTask] removeObject:task];
                *stop = YES;
            }
        }];
    }
}

#pragma mark - **************** 开始监听网络
+ (BOOL)isNetwork {
    return [AFNetworkReachabilityManager sharedManager].reachable;
}

+ (BOOL)isWWANNetwork {
    return [AFNetworkReachabilityManager sharedManager].reachableViaWWAN;
}

+ (BOOL)isWiFiNetwork {
    return [AFNetworkReachabilityManager sharedManager].reachableViaWiFi;
}

/**
 存储着所有的请求task数组
 */
+ (NSMutableArray *)allSessionTask {
    if (!_allSessionTask) {
        _allSessionTask = [[NSMutableArray alloc] init];
    }
    return _allSessionTask;
}

#pragma mark - **************** 初始化AFHTTPSessionManager相关属性
/**
 开始监测网络状态
 */
+ (void)load {
    [[AFNetworkReachabilityManager sharedManager] startMonitoring];
}
/**
 *  所有的HTTP请求共享一个AFHTTPSessionManager
 *  原理参考地址:http://www.jianshu.com/p/5969bbb4af9f
 */
+ (void)initialize {
    _sessionManager = [AFHTTPSessionManager manager];
    _sessionManager.requestSerializer.timeoutInterval = kRequestTimeoutInterval;
    AFJSONResponseSerializer *response = [[AFJSONResponseSerializer alloc] init];
    response.removesKeysWithNullValues = YES;
    _sessionManager.responseSerializer = response;
    _sessionManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/plain", @"text/javascript", @"text/xml", @"image/*", nil];
    // 打开状态栏的等待菊花
//    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
}

#pragma mark - 重置AFHTTPSessionManager相关属性
/// 设置请求头
+ (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
    [_sessionManager.requestSerializer setValue:value forHTTPHeaderField:field];
}
@end
